#ifdef OPENDDS_SECURITY

#include <dds/DCPS/security/AccessControlBuiltInImpl.h>
#include <dds/DCPS/security/OpenSSL_init.h>
#include <dds/DCPS/security/framework/Properties.h>
#include <dds/DCPS/security/TokenWriter.h>
#include <dds/DCPS/Service_Participant.h>

#include "ace/config-lite.h"

#ifdef ACE_HAS_CPP11
#  define OPENDDS_HAS_STD_SHARED_PTR
#endif

#include <dds/DdsDcpsC.h>
#ifdef OPENDDS_HAS_STD_SHARED_PTR
#include <memory>
#else
#include <ace/Bound_Ptr.h>
#include <ace/Null_Mutex.h>
#endif
// These are just used to meet signature requirements for a test
#include <gtestWrapper.h>

#include <sstream>
#include <fstream>

using namespace OpenDDS::Security;
using DDS::Property_t;
using DDS::PropertySeq;
using DDS::DomainParticipantQos;
using namespace testing;


static const char* Expected_Permissions_Token_Class_Id ="DDS:Access:Permissions:1.0";
static const char* Expected_Permissions_Cred_Token_Class_Id ="DDS:Access:PermissionsCredential";
//static const char* identity_ca_file = "certs/opendds_identity_ca_cert.pem";
static const char* mock_1_cert_file = "../security/certs/identity/test_participant_01_cert.pem";
static const char* perm_mock_1_join_p7s_file = "../security/permissions/permissions_test_participant_01_JoinDomain_signed.p7s";
static const char* remote_subject_name = "/C=US/ST=CO/O=Object Computing/CN=CN_TEST_DDS-SECURITY_OCI_OPENDDS/emailAddress=support@objectcomputing.com";

namespace {

// Mock classes for the AccessControl interface
// Initially generated by gmock_gen.py
class MockDataWriter : public DDS::DataWriter {
 public:
#ifdef OPENDDS_HAS_STD_SHARED_PTR
  typedef std::shared_ptr<MockDataWriter> SmartPtr;
#else
  typedef ACE_Strong_Bound_Ptr<MockDataWriter, ACE_Null_Mutex> SmartPtr;
#endif
  MOCK_METHOD1(set_qos, ::DDS::ReturnCode_t(const ::DDS::DataWriterQos & qos));
  MOCK_METHOD1(get_qos,
      ::DDS::ReturnCode_t(::DDS::DataWriterQos & qos));
  MOCK_METHOD2(set_listener,
      ::DDS::ReturnCode_t(::DDS::DataWriterListener_ptr a_listener, ::DDS::StatusMask mask));
  MOCK_METHOD0(get_listener,
      ::DDS::DataWriterListener_ptr(void));
  MOCK_METHOD0(get_topic,
      ::DDS::Topic_ptr(void));
  MOCK_METHOD0(get_publisher,
      ::DDS::Publisher_ptr(void));
  MOCK_METHOD1(wait_for_acknowledgments,
      ::DDS::ReturnCode_t(const ::DDS::Duration_t & max_wait));
  MOCK_METHOD1(get_liveliness_lost_status,
      ::DDS::ReturnCode_t(::DDS::LivelinessLostStatus & status));
  MOCK_METHOD1(get_offered_deadline_missed_status,
      ::DDS::ReturnCode_t(::DDS::OfferedDeadlineMissedStatus & status));
  MOCK_METHOD1(get_offered_incompatible_qos_status,
      ::DDS::ReturnCode_t(::DDS::OfferedIncompatibleQosStatus & status));
  MOCK_METHOD1(get_publication_matched_status,
      ::DDS::ReturnCode_t(::DDS::PublicationMatchedStatus & status));
  MOCK_METHOD0(assert_liveliness,
      ::DDS::ReturnCode_t(void));
  MOCK_METHOD1(get_matched_subscriptions,
      ::DDS::ReturnCode_t(::DDS::InstanceHandleSeq & subscription_handles));
  MOCK_METHOD2(get_matched_subscription_data,
      ::DDS::ReturnCode_t(::DDS::SubscriptionBuiltinTopicData & subscription_data, ::DDS::InstanceHandle_t subscription_handle));

  MOCK_METHOD0(enable,
      ::DDS::ReturnCode_t(void));
  MOCK_METHOD0(get_statuscondition,
      ::DDS::StatusCondition_ptr(void));
  MOCK_METHOD0(get_status_changes,
    ::DDS::StatusMask(void));
  MOCK_METHOD0(get_instance_handle,
    ::DDS::InstanceHandle_t(void));
};

class MockDataReader : public DDS::DataReader {
 public:
#ifdef OPENDDS_HAS_STD_SHARED_PTR
    typedef std::shared_ptr<MockDataReader> SmartPtr;
#else
    typedef ACE_Strong_Bound_Ptr<MockDataReader, ACE_Null_Mutex> SmartPtr;
#endif

  MOCK_METHOD3(create_readcondition,
      ::DDS::ReadCondition_ptr(::DDS::SampleStateMask sample_states, ::DDS::ViewStateMask view_states, ::DDS::InstanceStateMask instance_states));
#ifndef OPENDDS_NO_QUERY_CONDITION
  MOCK_METHOD5(create_querycondition,
      ::DDS::QueryCondition_ptr(::DDS::SampleStateMask sample_states, ::DDS::ViewStateMask view_states, ::DDS::InstanceStateMask instance_states, const char * query_expression, const ::DDS::StringSeq & query_parameters));
#endif // OPENDDS_NO_QUERY_CONDITION
  MOCK_METHOD1(delete_readcondition,
      ::DDS::ReturnCode_t(::DDS::ReadCondition_ptr a_condition));
  MOCK_METHOD0(delete_contained_entities,
      ::DDS::ReturnCode_t(void));
  MOCK_METHOD1(set_qos,
      ::DDS::ReturnCode_t(const ::DDS::DataReaderQos & qos));
  MOCK_METHOD1(get_qos,
      ::DDS::ReturnCode_t(::DDS::DataReaderQos & qos));
  MOCK_METHOD2(set_listener,
      ::DDS::ReturnCode_t(::DDS::DataReaderListener_ptr a_listener, ::DDS::StatusMask mask));
  MOCK_METHOD0(get_listener,
      ::DDS::DataReaderListener_ptr(void));
  MOCK_METHOD0(get_topicdescription,
      ::DDS::TopicDescription_ptr(void));
  MOCK_METHOD0(get_subscriber,
      ::DDS::Subscriber_ptr(void));
  MOCK_METHOD1(get_sample_rejected_status,
      ::DDS::ReturnCode_t(::DDS::SampleRejectedStatus & status));
  MOCK_METHOD1(get_liveliness_changed_status,
      ::DDS::ReturnCode_t(::DDS::LivelinessChangedStatus & status));
  MOCK_METHOD1(get_requested_deadline_missed_status,
      ::DDS::ReturnCode_t(::DDS::RequestedDeadlineMissedStatus & status));
  MOCK_METHOD1(get_requested_incompatible_qos_status,
      ::DDS::ReturnCode_t(::DDS::RequestedIncompatibleQosStatus & status));
  MOCK_METHOD1(get_subscription_matched_status,
      ::DDS::ReturnCode_t(::DDS::SubscriptionMatchedStatus & status));
  MOCK_METHOD1(get_sample_lost_status,
      ::DDS::ReturnCode_t(::DDS::SampleLostStatus & status));
  MOCK_METHOD1(wait_for_historical_data,
      ::DDS::ReturnCode_t(const ::DDS::Duration_t & max_wait));
  MOCK_METHOD1(get_matched_publications,
      ::DDS::ReturnCode_t(::DDS::InstanceHandleSeq & publication_handles));
  MOCK_METHOD2(get_matched_publication_data,
      ::DDS::ReturnCode_t(::DDS::PublicationBuiltinTopicData & publication_data, ::DDS::InstanceHandle_t publication_handle));

  MOCK_METHOD0(enable,
      ::DDS::ReturnCode_t(void));
  MOCK_METHOD0(get_statuscondition,
      ::DDS::StatusCondition_ptr(void));
  MOCK_METHOD0(get_status_changes,
    ::DDS::StatusMask(void));
  MOCK_METHOD0(get_instance_handle,
    ::DDS::InstanceHandle_t(void));
};

class MockAuthentication : public DDS::Security::Authentication {
 public:
#ifdef OPENDDS_HAS_STD_SHARED_PTR
    typedef std::shared_ptr<MockAuthentication> SmartPtr;
#else
    typedef ACE_Strong_Bound_Ptr<MockAuthentication, ACE_Null_Mutex> SmartPtr;
 #endif

  MOCK_METHOD6(validate_local_identity,
      ::DDS::Security::ValidationResult_t(::DDS::Security::IdentityHandle & local_identity_handle, ::OpenDDS::DCPS::GUID_t & adjusted_participant_guid, ::DDS::Security::DomainId_t domain_id, const ::DDS::DomainParticipantQos & participant_qos, const ::OpenDDS::DCPS::GUID_t & candidate_participant_guid, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD3(get_identity_token,
      CORBA::Boolean(::DDS::Security::IdentityToken & identity_token, ::DDS::Security::IdentityHandle handle, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD3(get_identity_status_token,
      CORBA::Boolean(::DDS::Security::IdentityStatusToken & identity_status_token, ::DDS::Security::IdentityHandle handle, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD4(set_permissions_credential_and_token,
      CORBA::Boolean(::DDS::Security::IdentityHandle handle, const ::DDS::Security::PermissionsCredentialToken & permissions_credential, const ::DDS::Security::PermissionsToken & permissions_token, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD7(validate_remote_identity,
      ::DDS::Security::ValidationResult_t(::DDS::Security::IdentityHandle & remote_identity_handle, ::DDS::Security::AuthRequestMessageToken & local_auth_request_token, const ::DDS::Security::AuthRequestMessageToken & remote_auth_request_token, ::DDS::Security::IdentityHandle local_identity_handle, const ::DDS::Security::IdentityToken & remote_identity_token, const ::OpenDDS::DCPS::GUID_t & remote_participant_guid, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD6(begin_handshake_request,
      ::DDS::Security::ValidationResult_t(::DDS::Security::HandshakeHandle & handshake_handle, ::DDS::Security::HandshakeMessageToken & handshake_message, ::DDS::Security::IdentityHandle initiator_identity_handle, ::DDS::Security::IdentityHandle replier_identity_handle, const ::DDS::OctetSeq & serialized_local_participant_data, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD6(begin_handshake_reply,
      ::DDS::Security::ValidationResult_t(::DDS::Security::HandshakeHandle & handshake_handle, ::DDS::Security::HandshakeMessageToken & handshake_message_out, ::DDS::Security::IdentityHandle initiator_identity_handle, ::DDS::Security::IdentityHandle replier_identity_handle, const ::DDS::OctetSeq & serialized_local_participant_data, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD4(process_handshake,
      ::DDS::Security::ValidationResult_t(::DDS::Security::HandshakeMessageToken & handshake_message_out, const ::DDS::Security::HandshakeMessageToken & handshake_message_in, ::DDS::Security::HandshakeHandle handshake_handle, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD2(get_shared_secret,
      ::DDS::Security::SharedSecretHandle*(::DDS::Security::HandshakeHandle handshake_handle, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD3(get_authenticated_peer_credential_token,
      CORBA::Boolean(::DDS::Security::AuthenticatedPeerCredentialToken & peer_credential_token, ::DDS::Security::HandshakeHandle handshake_handle, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD2(set_listener,
      CORBA::Boolean(::DDS::Security::AuthenticationListener_ptr listener, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD2(return_identity_token,
      CORBA::Boolean(const ::DDS::Security::IdentityToken & token, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD2(return_identity_status_token,
      CORBA::Boolean(const ::DDS::Security::IdentityStatusToken & token, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD2(return_authenticated_peer_credential_token,
      CORBA::Boolean(const ::DDS::Security::AuthenticatedPeerCredentialToken & peer_credential_token, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD2(return_handshake_handle,
      CORBA::Boolean(::DDS::Security::HandshakeHandle handshake_handle, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD2(return_identity_handle,
      CORBA::Boolean(::DDS::Security::IdentityHandle identity_handle, ::DDS::Security::SecurityException & ex));
  MOCK_METHOD2(return_sharedsecret_handle,
      CORBA::Boolean(::DDS::Security::SharedSecretHandle* sharedsecret_handle, ::DDS::Security::SecurityException & ex));
};

class MockAccessControlListener : public DDS::Security::AccessControlListener
{
  public:
#ifdef OPENDDS_HAS_STD_SHARED_PTR
    typedef std::shared_ptr<MockAccessControlListener> SmartPtr;
#else
    typedef ACE_Strong_Bound_Ptr<MockAccessControlListener, ACE_Null_Mutex> SmartPtr;
#endif

  MOCK_METHOD2(on_revoke_permissions,
    CORBA::Boolean(::DDS::Security::AccessControl_ptr plugin, ::DDS::Security::PermissionsHandle handle));
};

// A Mock can't be made for this class as it has no abstract interface,
// but the constructor isn't public either, so it can only exist by creating
// a child class
class FakeDynamicData : public virtual DDS::DynamicData
{
public:
#ifdef OPENDDS_HAS_STD_SHARED_PTR
    typedef std::shared_ptr<FakeDynamicData> SmartPtr;
#else
    typedef ACE_Strong_Bound_Ptr<FakeDynamicData, ACE_Null_Mutex> SmartPtr;
#endif

  MOCK_METHOD0(type, DDS::DynamicType_ptr(void));
  MOCK_METHOD2(get_descriptor, DDS::ReturnCode_t(DDS::MemberDescriptor *& value, DDS::MemberId id));
  MOCK_METHOD2(set_descriptor, DDS::ReturnCode_t(DDS::MemberId id, DDS::MemberDescriptor * value));
  MOCK_METHOD1(equals, CORBA::Boolean(DDS::DynamicData_ptr other));
  MOCK_METHOD1(get_member_id_by_name, DDS::MemberId(const char * name));
  MOCK_METHOD1(get_member_id_at_index, DDS::MemberId(CORBA::ULong index));
  MOCK_METHOD0(get_item_count, CORBA::ULong(void));
  MOCK_METHOD0(clear_all_values, DDS::ReturnCode_t(void));
  MOCK_METHOD0(clear_nonkey_values, DDS::ReturnCode_t(void));
  MOCK_METHOD1(clear_value, DDS::ReturnCode_t(DDS::MemberId id));
  MOCK_METHOD1(loan_value, DDS::DynamicData_ptr(DDS::MemberId id));
  MOCK_METHOD1(return_loaned_value, DDS::ReturnCode_t(DDS::DynamicData_ptr value));
  MOCK_METHOD0(clone, DDS::DynamicData_ptr(void));
  MOCK_METHOD2(get_int32_value, DDS::ReturnCode_t(CORBA::Long & value, DDS::MemberId id));
  MOCK_METHOD2(set_int32_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::Long value));
  MOCK_METHOD2(get_uint32_value, DDS::ReturnCode_t(CORBA::ULong & value, DDS::MemberId id));
  MOCK_METHOD2(set_uint32_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::ULong value));
  MOCK_METHOD2(get_int8_value, DDS::ReturnCode_t(CORBA::Int8 & value, DDS::MemberId id));
  MOCK_METHOD2(set_int8_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::Int8 value));
  MOCK_METHOD2(get_uint8_value, DDS::ReturnCode_t(CORBA::UInt8 & value, DDS::MemberId id));
  MOCK_METHOD2(set_uint8_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::UInt8 value));
  MOCK_METHOD2(get_int16_value, DDS::ReturnCode_t(CORBA::Short & value, DDS::MemberId id));
  MOCK_METHOD2(set_int16_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::Short value));
  MOCK_METHOD2(get_uint16_value, DDS::ReturnCode_t(CORBA::UShort & value, DDS::MemberId id));
  MOCK_METHOD2(set_uint16_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::UShort value));
  MOCK_METHOD2(get_int64_value, DDS::ReturnCode_t(CORBA::LongLong & value, DDS::MemberId id));
  MOCK_METHOD2(set_int64_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::LongLong value));
  MOCK_METHOD2(get_uint64_value, DDS::ReturnCode_t(CORBA::ULongLong & value, DDS::MemberId id));
  MOCK_METHOD2(set_uint64_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::ULongLong value));
  MOCK_METHOD2(get_float32_value, DDS::ReturnCode_t(CORBA::Float & value, DDS::MemberId id));
  MOCK_METHOD2(set_float32_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::Float value));
  MOCK_METHOD2(get_float64_value, DDS::ReturnCode_t(CORBA::Double & value, DDS::MemberId id));
  MOCK_METHOD2(set_float64_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::Double value));
  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244)
  MOCK_METHOD2(get_float128_value, DDS::ReturnCode_t(CORBA::LongDouble & value, DDS::MemberId id));
  MOCK_METHOD2(set_float128_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::LongDouble value));
  GTEST_DISABLE_MSC_WARNINGS_POP_()
  MOCK_METHOD2(get_char8_value, DDS::ReturnCode_t(CORBA::Char & value, DDS::MemberId id));
  MOCK_METHOD2(set_char8_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::Char value));
  MOCK_METHOD2(get_char16_value, DDS::ReturnCode_t(CORBA::WChar & value, DDS::MemberId id));
  MOCK_METHOD2(set_char16_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::WChar value));
  MOCK_METHOD2(get_byte_value, DDS::ReturnCode_t(CORBA::Octet & value, DDS::MemberId id));
  MOCK_METHOD2(set_byte_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::Octet value));
  MOCK_METHOD2(get_boolean_value, DDS::ReturnCode_t(CORBA::Boolean & value, DDS::MemberId id));
  MOCK_METHOD2(set_boolean_value, DDS::ReturnCode_t(DDS::MemberId id, CORBA::Boolean value));
  MOCK_METHOD2(get_string_value, DDS::ReturnCode_t(char *& value, DDS::MemberId id));
  MOCK_METHOD2(set_string_value, DDS::ReturnCode_t(DDS::MemberId id, const char * value));
  MOCK_METHOD2(get_wstring_value, DDS::ReturnCode_t(CORBA::WChar *& value, DDS::MemberId id));
  MOCK_METHOD2(set_wstring_value, DDS::ReturnCode_t(DDS::MemberId id, const CORBA::WChar * value));
  MOCK_METHOD2(get_complex_value, DDS::ReturnCode_t(DDS::DynamicData_ptr & value, DDS::MemberId id));
  MOCK_METHOD2(set_complex_value, DDS::ReturnCode_t(DDS::MemberId id, DDS::DynamicData_ptr value));
  MOCK_METHOD2(get_int32_values, DDS::ReturnCode_t(DDS::Int32Seq & value, DDS::MemberId id));
  MOCK_METHOD2(set_int32_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::Int32Seq & value));
  MOCK_METHOD2(get_uint32_values, DDS::ReturnCode_t(DDS::UInt32Seq & value, DDS::MemberId id));
  MOCK_METHOD2(set_uint32_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::UInt32Seq & value));
  MOCK_METHOD2(get_int8_values, DDS::ReturnCode_t(DDS::Int8Seq & value, DDS::MemberId id));
  MOCK_METHOD2(set_int8_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::Int8Seq & value));
  MOCK_METHOD2(get_uint8_values, DDS::ReturnCode_t(DDS::UInt8Seq & value, DDS::MemberId id));
  MOCK_METHOD2(set_uint8_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::UInt8Seq & value));
  MOCK_METHOD2(get_int16_values, DDS::ReturnCode_t(DDS::Int16Seq & value, DDS::MemberId id));
  MOCK_METHOD2(set_int16_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::Int16Seq & value));
  MOCK_METHOD2(get_uint16_values, DDS::ReturnCode_t(DDS::UInt16Seq & value, DDS::MemberId id));
  MOCK_METHOD2(set_uint16_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::UInt16Seq & value));
  MOCK_METHOD2(get_int64_values, DDS::ReturnCode_t(DDS::Int64Seq & value, DDS::MemberId id));
  MOCK_METHOD2(set_int64_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::Int64Seq & value));
  MOCK_METHOD2(get_uint64_values, DDS::ReturnCode_t(DDS::UInt64Seq & value, DDS::MemberId id));
  MOCK_METHOD2(set_uint64_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::UInt64Seq & value));
  MOCK_METHOD2(get_float32_values, DDS::ReturnCode_t(DDS::Float32Seq & value, DDS::MemberId id));
  MOCK_METHOD2(set_float32_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::Float32Seq & value));
  MOCK_METHOD2(get_float64_values, DDS::ReturnCode_t(DDS::Float64Seq & value, DDS::MemberId id));
  MOCK_METHOD2(set_float64_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::Float64Seq & value));
  MOCK_METHOD2(get_float128_values, DDS::ReturnCode_t(DDS::Float128Seq & value, DDS::MemberId id));
  MOCK_METHOD2(set_float128_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::Float128Seq & value));
  MOCK_METHOD2(get_char8_values, DDS::ReturnCode_t(DDS::CharSeq & value, DDS::MemberId id));
  MOCK_METHOD2(set_char8_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::CharSeq & value));
  MOCK_METHOD2(get_char16_values, DDS::ReturnCode_t(DDS::WcharSeq & value, DDS::MemberId id));
  MOCK_METHOD2(set_char16_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::WcharSeq & value));
  MOCK_METHOD2(get_byte_values, DDS::ReturnCode_t(DDS::ByteSeq & value, DDS::MemberId id));
  MOCK_METHOD2(set_byte_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::ByteSeq & value));
  MOCK_METHOD2(get_boolean_values, DDS::ReturnCode_t(DDS::BooleanSeq & value, DDS::MemberId id));
  MOCK_METHOD2(set_boolean_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::BooleanSeq & value));
  MOCK_METHOD2(get_string_values, DDS::ReturnCode_t(DDS::StringSeq & value, DDS::MemberId id));
  MOCK_METHOD2(set_string_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::StringSeq & value));
  MOCK_METHOD2(get_wstring_values, DDS::ReturnCode_t(DDS::WstringSeq & value, DDS::MemberId id));
  MOCK_METHOD2(set_wstring_values, DDS::ReturnCode_t(DDS::MemberId id, const DDS::WstringSeq & value));
};

class dds_DCPS_security_AccessControlBuiltInImpl : public Test
{
public:
  dds_DCPS_security_AccessControlBuiltInImpl()
  : auth_plugin_(new MockAuthentication())
  , test_class_()
  {
    perm_ca_.name = DDS::Security::Properties::AccessPermissionsCA;
    perm_ca_.value = "file:../security/certs/permissions/permissions_ca_cert.pem";
    perm_ca_.propagate = false;

    gov_0_p7s_.name = DDS::Security::Properties::AccessGovernance;
    gov_0_p7s_.value = "file:../security/governance/governance_SC0_SecurityDisabled_signed.p7s";
    gov_0_p7s_.propagate = false;

    gov_1_p7s_.name = DDS::Security::Properties::AccessGovernance;
    gov_1_p7s_.value = "file:../security/governance/governance_SC1_ProtectedDomain1_signed.p7s";
    gov_1_p7s_.propagate = false;

    gov_2_p7s_.name = DDS::Security::Properties::AccessGovernance;
    gov_2_p7s_.value = "file:../security/governance/governance_SC2_ProtectedDomain2_signed.p7s";
    gov_2_p7s_.propagate = false;

    gov_3_p7s_.name = DDS::Security::Properties::AccessGovernance;
    gov_3_p7s_.value = "file:../security/governance/governance_SC3_ProtectedDomain3_signed.p7s";
    gov_3_p7s_.propagate = false;

    gov_4_p7s_.name = DDS::Security::Properties::AccessGovernance;
    gov_4_p7s_.value = "file:../security/governance/governance_SC4_ProtectedDomain4_signed.p7s";
    gov_4_p7s_.propagate = false;

    gov_5_p7s_.name = DDS::Security::Properties::AccessGovernance;
    gov_5_p7s_.value = "file:../security/governance/governance_SC5_ProtectedDomain5_signed.p7s";
    gov_5_p7s_.propagate = false;

    gov_6_p7s_.name = DDS::Security::Properties::AccessGovernance;
    gov_6_p7s_.value = "file:../security/governance/governance_SC6_ProtectedDomain6_signed.p7s";
    gov_6_p7s_.propagate = false;

    perm_allowall_p7s_.name = DDS::Security::Properties::AccessPermissions;
    perm_allowall_p7s_.value = "file:../security/permissions/permissions_test_participant_01_JoinDomain_signed.p7s";
    perm_allowall_p7s_.propagate = false;

    perm_topic_p7s_.name = DDS::Security::Properties::AccessPermissions;
    perm_topic_p7s_.value = "file:../security/permissions/permissions_test_participant_01_TopicLevel_signed.p7s";
    perm_topic_p7s_.propagate = false;

    perm_topic2_p7s_.name = DDS::Security::Properties::AccessPermissions;
    perm_topic2_p7s_.value = "file:../security/permissions/permissions_test_participant_01_TopicLevel_2_signed.p7s";
    perm_topic2_p7s_.propagate = false;

    perm_date_p7s_.name = DDS::Security::Properties::AccessPermissions;
    perm_date_p7s_.value = "file:../security/permissions/permissions_test_participant_01_NotBefore_signed.p7s";
    perm_date_p7s_.propagate = false;

    perm_action_validity_p7s_.name = DDS::Security::Properties::AccessPermissions;
    perm_action_validity_p7s_.value = "file:../security/permissions/permissions_test_participant_01_ActionValidity_signed.p7s";
    perm_action_validity_p7s_.propagate = false;

    perm_dateoffset_p7s_.name = DDS::Security::Properties::AccessPermissions;
    perm_dateoffset_p7s_.value = "file:../security/permissions/permissions_test_participant_01_NotBeforeOffset_signed.p7s";
    perm_dateoffset_p7s_.propagate = false;

    perm_parts_p7s_.name = DDS::Security::Properties::AccessPermissions;
    perm_parts_p7s_.value =
      "file:../security/permissions/permissions_test_participant_01_TopicLevel_Partitions_Default_signed.p7s";
    perm_parts_p7s_.propagate = false;

    perm_two_partitions_p7s_.name = DDS::Security::Properties::AccessPermissions;
    perm_two_partitions_p7s_.value =
      "file:../security/attributes/permissions/permissions_test_participant_01_partitions_signed.p7s";
    perm_two_partitions_p7s_.propagate = false;

    add_property(perm_ca_);
    add_property(gov_0_p7s_);
    add_property(perm_allowall_p7s_);

    ::DDS::OctetSeq Empty_Seq;

    // Set up correct returns from get_identity_token for our Google Mock version of the Authentication Builtin Plugin

    ON_CALL(*dynamic_cast<MockAuthentication*>(auth_plugin_.get()), get_identity_token(A<DDS::Security::IdentityToken&>(), A<DDS::Security::IdentityHandle>(), A<DDS::Security::SecurityException&>())).WillByDefault(Return(false));

    DDS::Security::IdentityToken local_id_token;
    OpenDDS::Security::TokenWriter local_tw(local_id_token);
    local_tw.add_property("dds.cert.sn", "CN=Ozzie Ozmann,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU");

    EXPECT_CALL(*dynamic_cast<MockAuthentication*>(auth_plugin_.get()), get_identity_token(A<DDS::Security::IdentityToken&>(), 1, A<DDS::Security::SecurityException&>())).WillRepeatedly(DoAll(SetArgReferee<0>(local_id_token), Return(true)));
  }

  void TearDown() {
    TheServiceParticipant->shutdown();
  }

  static void SetUpTestCase () {
    openssl_init();
  }

  ~dds_DCPS_security_AccessControlBuiltInImpl()
  {
  }

  void set_up_service_participant() {
    int arg_count = 3;
    const char* params[3] = { "AccessControlBuiltInImpl", " -ORBDebugLevel 1", " -DCPSConfigFile sec_base.ini" };
    DDS::DomainParticipantFactory_var dpf = TheParticipantFactoryWithArgs(arg_count, const_cast<char**>(params));
  }

  void add_property(const Property_t& p)
  {
    PropertySeq& seq = domain_participant_qos_.property.value;
    const CORBA::ULong len = seq.length();
    seq.length(len + 1);
    seq[len] = p;
  }

  void add_or_replace_property(const Property_t& p)
  {
    PropertySeq& seq = domain_participant_qos_.property.value;
    for (unsigned int i = 0; i < seq.length(); ++i) {
      if (std::strcmp(seq[i].name, p.name) == 0) {
        seq[i] = p;
        return;
      }
    }
    add_property(p);
  }

  std::string extract_file_name(const std::string& file_parm) {
    std::string del = ":";
    size_t pos = file_parm.find_last_of(del);
    if ((pos > 0 ) && (pos != file_parm.length() - 1) ) {
        return file_parm.substr(pos + 1);
    } else {
        return std::string("");
    }
  }

  std::string get_file_contents(const char *filename) {
    std::ifstream in(filename, std::ios::in | std::ios::binary);
    if (in)
    {
        std::ostringstream contents;
        contents << in.rdbuf();
        in.close();
        return(contents.str());
    }
    throw(errno);
  }

  CORBA::Boolean clean_smime_content(std::string& content_) {
    std::string search_str("<?xml");

    size_t found = content_.find(search_str);
    if (found!=std::string::npos){
        std::string holder_(content_.substr(found));
        content_.clear();
        content_.assign(holder_);
        return true;
    }

    return false;
  }

  DDS::Security::AccessControl& get_inst()
  {
    return test_class_;
  }

  DomainParticipantQos domain_participant_qos_;
  MockAuthentication::SmartPtr auth_plugin_;

  Property_t perm_ca_;
  Property_t gov_0_p7s_, gov_1_p7s_, gov_2_p7s_, gov_3_p7s_, gov_4_p7s_, gov_5_p7s_, gov_6_p7s_;
  Property_t perm_allowall_p7s_, perm_topic_p7s_, perm_topic2_p7s_;
  Property_t perm_date_p7s_, perm_dateoffset_p7s_;
  Property_t perm_parts_p7s_, perm_two_partitions_p7s_;
  Property_t perm_action_validity_p7s_;

private:

  AccessControlBuiltInImpl test_class_;
};

}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, validate_local_permissions_InvalidInput)
{
  ::DDS::DomainParticipantQos qos;
  ::DDS::Security::SecurityException ex;
  EXPECT_EQ(DDS::HANDLE_NIL,
    get_inst().validate_local_permissions(0, 1, 1, qos, ex));

  EXPECT_EQ(DDS::HANDLE_NIL,
    get_inst().validate_local_permissions(auth_plugin_.get(), DDS::HANDLE_NIL, 1, qos, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, validate_local_permissions_Success)
{
  ::DDS::Security::SecurityException ex;

  ::DDS::Security::PermissionsHandle out_handle =
    get_inst().validate_local_permissions(auth_plugin_.get(), 1, 1, domain_participant_qos_, ex);
  EXPECT_FALSE(DDS::HANDLE_NIL == out_handle);
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, validate_remote_permissions_InvalidInput)
{
  ::DDS::Security::PermissionsToken remote_perm;
  ::DDS::Security::AuthenticatedPeerCredentialToken remote_cred;
  ::DDS::Security::SecurityException ex;

  // Null authentication
  EXPECT_EQ(DDS::HANDLE_NIL, get_inst().validate_remote_permissions(
    0, 1, 2, remote_perm, remote_cred, ex));

  // Invalid local handle
  EXPECT_EQ(DDS::HANDLE_NIL, get_inst().validate_remote_permissions(
    auth_plugin_.get(), DDS::HANDLE_NIL, 2, remote_perm, remote_cred, ex));
  // Invalid remote handle
  EXPECT_EQ(DDS::HANDLE_NIL, get_inst().validate_remote_permissions(
    auth_plugin_.get(), 1, DDS::HANDLE_NIL, remote_perm, remote_cred, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, validate_remote_permissions_Success)
{
  ::DDS::Security::PermissionsToken remote_perm_token;
  ::DDS::Security::AuthenticatedPeerCredentialToken remote_apc_token;
  ::DDS::Security::SecurityException ex;

  remote_perm_token.class_id = Expected_Permissions_Token_Class_Id;
  remote_perm_token.properties.length(1);
  remote_perm_token.properties[0].name = "dds.perm.ca.sn";
  remote_perm_token.properties[0].value = remote_subject_name;

  std::string id(get_file_contents(mock_1_cert_file));
  std::string pf(get_file_contents(perm_mock_1_join_p7s_file));

  remote_apc_token.class_id = Expected_Permissions_Cred_Token_Class_Id;
  remote_apc_token.binary_properties.length(2);
  remote_apc_token.binary_properties[0].name = "c.id";
  remote_apc_token.binary_properties[0].value.length(static_cast<CORBA::ULong>(id.size()));
  memcpy(remote_apc_token.binary_properties[0].value.get_buffer(), id.c_str(), id.size());
  remote_apc_token.binary_properties[0].propagate = true;

  remote_apc_token.binary_properties[1].name = "c.perm";
  remote_apc_token.binary_properties[1].value.length(static_cast<CORBA::ULong>(pf.size()));
  memcpy(remote_apc_token.binary_properties[1].value.get_buffer(), pf.c_str(), pf.size());
  remote_apc_token.binary_properties[1].propagate = true;

  get_inst().validate_local_permissions(auth_plugin_.get(), 1, 1, domain_participant_qos_, ex);

  ::DDS::Security::PermissionsHandle remote_out_handle = get_inst().validate_remote_permissions(
    auth_plugin_.get(), 1, 2, remote_perm_token, remote_apc_token, ex);
  EXPECT_FALSE(DDS::HANDLE_NIL == remote_out_handle);
  std::cout << ex.message << std::endl;
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_participant_InvalidInput)
{
  ::DDS::DomainParticipantQos qos;
  ::DDS::Security::SecurityException ex;

  EXPECT_FALSE(get_inst().check_create_participant(
    DDS::HANDLE_NIL, 1, qos, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_participant_Success)
{
  ::DDS::DomainParticipantQos qos;
  ::DDS::Security::SecurityException ex;
    ::DDS::Security::PermissionsHandle out_handle =
            get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);
  EXPECT_FALSE(DDS::HANDLE_NIL == get_inst().check_create_participant(out_handle, 0, domain_participant_qos_, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_datawriter_InvalidInput)
{
  ::DDS::Security::PermissionsHandle permissions_handle = 1;
  ::DDS::Security::DomainId_t domain_id = 1;
  ::DDS::DataWriterQos qos;
  ::DDS::PartitionQosPolicy  partition;
  ::DDS::Security::DataTags  data_tag;
  ::DDS::Security::SecurityException ex;

  // Invalid handle
  EXPECT_FALSE(get_inst().check_create_datawriter(
    DDS::HANDLE_NIL,
    domain_id,
    "MyTopic",
    qos,
    partition,
    data_tag,
    ex));

  // Invalid topic name
  EXPECT_FALSE(get_inst().check_create_datawriter(
    permissions_handle,
    domain_id,
    0,
    qos,
    partition,
    data_tag,
    ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_datawriter_Success)
{
  ::DDS::Security::DomainId_t domain_id = 0;
  const char * topic_name = "Square";
  ::DDS::DataWriterQos qos;
  ::DDS::PartitionQosPolicy partition;
  ::DDS::Security::DataTags data_tag;
  ::DDS::Security::SecurityException ex;

  set_up_service_participant();
  add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::gov_6_p7s_);

  ::DDS::Security::PermissionsHandle out_handle =
          get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);

  partition.name.length(0);

  EXPECT_TRUE(get_inst().check_create_datawriter(
    out_handle,
    domain_id,
    topic_name,
    qos,
    partition,
    data_tag,
    ex));
  ASSERT_STREQ("", ex.message);
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_datawriter_default_Success)
{
  ::DDS::Security::DomainId_t domain_id = 0;
  const char * topic_name = "Rectangle";
  ::DDS::DataWriterQos qos;
  ::DDS::PartitionQosPolicy  partition;
  ::DDS::Security::DataTags  data_tag;
  ::DDS::Security::SecurityException ex;

  set_up_service_participant();
  add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::gov_6_p7s_);

  ::DDS::Security::PermissionsHandle out_handle =
      get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);

  EXPECT_TRUE(get_inst().check_create_datawriter(
      out_handle,
      domain_id,
      topic_name,
      qos,
      partition,
      data_tag,
      ex));
  ASSERT_STREQ("", ex.message);
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_datawriter_date_Fail)
{
    ::DDS::Security::DomainId_t domain_id = 0;
    const char * topic_name = "Square";
    ::DDS::DataWriterQos qos;
    ::DDS::PartitionQosPolicy  partition;
    ::DDS::Security::DataTags  data_tag;
    ::DDS::Security::SecurityException ex;

    set_up_service_participant();
    add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::gov_6_p7s_);
    add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::perm_date_p7s_);

    ::DDS::Security::PermissionsHandle out_handle =
        get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);

    partition.name.length(0);

    EXPECT_FALSE(get_inst().check_create_datawriter(
        out_handle,
        domain_id,
        topic_name,
        qos,
        partition,
        data_tag,
        ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_datawriter_action_validity_Fail)
{
    ::DDS::Security::DomainId_t domain_id = 0;
    const char * topic_name = "Triangle";
    ::DDS::DataWriterQos qos;
    ::DDS::PartitionQosPolicy  partition;
    ::DDS::Security::DataTags  data_tag;
    ::DDS::Security::SecurityException ex;

    set_up_service_participant();
    add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::gov_6_p7s_);
    add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::perm_action_validity_p7s_);

    ::DDS::Security::PermissionsHandle out_handle =
        get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);

    partition.name.length(0);

    EXPECT_FALSE(get_inst().check_create_datawriter(
        out_handle,
        domain_id,
        topic_name,
        qos,
        partition,
        data_tag,
        ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_datareader_InvalidInput)
{
  ::DDS::Security::PermissionsHandle permissions_handle = 1;
  ::DDS::Security::DomainId_t domain_id = 1;
  ::DDS::DataReaderQos qos;
  ::DDS::PartitionQosPolicy  partition;
  ::DDS::Security::DataTags  data_tag;
  ::DDS::Security::SecurityException ex;

  // Invalid handle
  EXPECT_FALSE(get_inst().check_create_datareader(
    DDS::HANDLE_NIL,
    domain_id,
    "MyTopic",
    qos,
    partition,
    data_tag,
    ex));

  // Invalid topic name
  EXPECT_FALSE(get_inst().check_create_datareader(
    permissions_handle,
    domain_id,
    0,
    qos,
    partition,
    data_tag,
    ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_datareader_Success)
{
  ::DDS::Security::DomainId_t domain_id = 0;
  const char * topic_name = "Square";
  ::DDS::DataReaderQos qos;
  ::DDS::PartitionQosPolicy  partition;
  ::DDS::Security::DataTags  data_tag;
  ::DDS::Security::SecurityException ex;

  set_up_service_participant();
  add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::gov_6_p7s_);

  ::DDS::Security::PermissionsHandle permissions_handle =
          get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);

  partition.name.length(0);

  EXPECT_TRUE(get_inst().check_create_datareader(
    permissions_handle,
    domain_id,
    topic_name,
    qos,
    partition,
    data_tag,
    ex));
  ASSERT_STREQ("", ex.message);
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_datareader_Partitions)
{
  static const DDS::Security::DomainId_t domain_id = 0;
  static const char topic_name[] = "Square";

  set_up_service_participant();
  add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::gov_6_p7s_);
  add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::perm_two_partitions_p7s_);

  ::DDS::Security::SecurityException ex;
  ::DDS::Security::PermissionsHandle permissions_handle =
    get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);

  ::DDS::PartitionQosPolicy partition;
  partition.name.length(1);
  partition.name[0] = "foo";

  EXPECT_TRUE(get_inst().check_create_datareader(
    permissions_handle,
    domain_id,
    topic_name,
    DDS::DataReaderQos(),
    partition,
    DDS::Security::DataTags(),
    ex));
  ASSERT_STREQ("", ex.message);
}

//TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_permissions_timer_Success)
//{
//
//    ::DDS::Security::DomainId_t domain_id = 0;
//    const char * topic_name = "Square";
//    ::DDS::DataReaderQos qos;
//    ::DDS::TopicQos tqos;
//    ::DDS::PartitionQosPolicy  partition;
//    ::DDS::Security::DataTags  data_tag;
//    ::DDS::Security::SecurityException ex;
//
//    set_up_service_participant();
//    add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::gov_6_p7s_);
//
//    ::DDS::Security::PermissionsHandle permissions_handle =
//        get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);
//
//    partition.name.length(0);
//
//    EXPECT_TRUE(get_inst().check_create_datareader(
//        permissions_handle,
//        domain_id,
//        topic_name,
//        qos,
//        partition,
//        data_tag,
//        ex));
//
//    // Delay here...
//    int milliseconds = 1000 * 20;
//    clock_t start_time = clock();
//
//    while (clock() < start_time + milliseconds)
//        ;
//
//    EXPECT_TRUE(get_inst().check_create_topic(
//        permissions_handle, domain_id, topic_name, tqos, ex));
//
//    // Delay a little more...
//    milliseconds = 1000 * 25;
//    start_time = clock();
//
//    while (clock() < start_time + milliseconds)
//        ;
//
//    EXPECT_FALSE(get_inst().check_create_topic(
//        permissions_handle, domain_id, topic_name, tqos, ex));
//}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_datareader_default_Success)
{
  ::DDS::Security::DomainId_t domain_id = 0;
  const char * topic_name = "Oval";
  ::DDS::DataReaderQos qos;
  ::DDS::PartitionQosPolicy  partition;
  ::DDS::Security::DataTags  data_tag;
  ::DDS::Security::SecurityException ex;

  set_up_service_participant();
  add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::gov_6_p7s_);

  ::DDS::Security::PermissionsHandle permissions_handle =
      get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);

  partition.name.length(0);

  EXPECT_TRUE(get_inst().check_create_datareader(
      permissions_handle,
      domain_id,
      topic_name,
      qos,
      partition,
      data_tag,
      ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_datareader_action_validity_Fail)
{
  ::DDS::Security::DomainId_t domain_id = 0;
  const char * topic_name = "Square";
  ::DDS::DataReaderQos qos;
  ::DDS::PartitionQosPolicy  partition;
  ::DDS::Security::DataTags  data_tag;
  ::DDS::Security::SecurityException ex;

  set_up_service_participant();
  add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::gov_6_p7s_);
  add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::perm_action_validity_p7s_);

  ::DDS::Security::PermissionsHandle permissions_handle =
      get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);

  partition.name.length(0);

  EXPECT_FALSE(get_inst().check_create_datareader(
      permissions_handle,
      domain_id,
      topic_name,
      qos,
      partition,
      data_tag,
      ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_topic_InvalidInput)
{
  ::DDS::Security::PermissionsHandle permissions_handle = 1;
  ::DDS::Security::DomainId_t domain_id = 1;
  ::DDS::TopicQos qos;
  ::DDS::Security::SecurityException ex;

  // Invalid handle
  EXPECT_FALSE(get_inst().check_create_topic(
    DDS::HANDLE_NIL, domain_id, "MyTopic", qos, ex));

  // Invalid topic name
  EXPECT_FALSE(get_inst().check_create_topic(
    permissions_handle, domain_id, 0, qos, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_topic_Success)
{
  ::DDS::Security::DomainId_t domain_id = 0;
  const char * topic_name = "Square";
  ::DDS::TopicQos qos;
  ::DDS::Security::SecurityException ex;


  ::DDS::Security::PermissionsHandle permissions_handle = get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);
  EXPECT_TRUE(get_inst().check_create_topic(
    permissions_handle, domain_id, topic_name, qos, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_create_topic_default_Success)
{
    ::DDS::Security::DomainId_t domain_id = 0;
    const char * topic_name = "Polygon";
    ::DDS::TopicQos qos;
    ::DDS::Security::SecurityException ex;


    ::DDS::Security::PermissionsHandle permissions_handle = get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);
    EXPECT_TRUE(get_inst().check_create_topic(
        permissions_handle, domain_id, topic_name, qos, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_local_datawriter_register_instance_InvalidInput)
{
  ::DDS::Security::PermissionsHandle permissions_handle = 1;
  MockDataWriter::SmartPtr writer(new MockDataWriter());
  FakeDynamicData::SmartPtr key(new FakeDynamicData());
  ::DDS::Security::SecurityException ex;

  // Nil input handle
  EXPECT_FALSE(get_inst().check_local_datawriter_register_instance(
    DDS::HANDLE_NIL, writer.get(), key.get(), ex));

  // Null writer
  EXPECT_FALSE(get_inst().check_local_datawriter_register_instance(
    permissions_handle, 0, key.get(), ex));

  // Null key
  EXPECT_FALSE(get_inst().check_local_datawriter_register_instance(
    permissions_handle, writer.get(), 0, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_local_datawriter_register_instance_Success)
{
  ::DDS::Security::PermissionsHandle permissions_handle = 1;
  MockDataWriter::SmartPtr writer(new MockDataWriter());
  FakeDynamicData::SmartPtr key(new FakeDynamicData());
  ::DDS::Security::SecurityException ex;

  EXPECT_TRUE(get_inst().check_local_datawriter_register_instance(
    permissions_handle, writer.get(), key.get(), ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_local_datawriter_dispose_instance_InvalidInput)
{
  ::DDS::Security::PermissionsHandle permissions_handle = 1;
  MockDataWriter::SmartPtr writer(new MockDataWriter());
  FakeDynamicData::SmartPtr key(new FakeDynamicData());
  ::DDS::Security::SecurityException ex;

  // Nil input handle
  EXPECT_FALSE(get_inst().check_local_datawriter_dispose_instance(
    DDS::HANDLE_NIL, writer.get(), key.get(), ex));

  // Null writer
  EXPECT_FALSE(get_inst().check_local_datawriter_dispose_instance(
    permissions_handle, 0, key.get(), ex));

  // Null key
  EXPECT_FALSE(get_inst().check_local_datawriter_dispose_instance(
    permissions_handle, writer.get(), 0, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_local_datawriter_dispose_instance_Success)
{
  ::DDS::Security::PermissionsHandle permissions_handle = 1;
  MockDataWriter::SmartPtr writer(new MockDataWriter());
  FakeDynamicData::SmartPtr key(new FakeDynamicData());
  ::DDS::Security::SecurityException ex;

  EXPECT_TRUE(get_inst().check_local_datawriter_dispose_instance(
    permissions_handle, writer.get(), key.get(), ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_participant_InvalidInput)
{
  ::DDS::Security::DomainId_t domain_id = 1;
  ::DDS::Security::ParticipantBuiltinTopicDataSecure participant_data;
  ::DDS::Security::SecurityException ex;

  // Nil input handle
  EXPECT_FALSE(get_inst().check_remote_participant(
    DDS::HANDLE_NIL, domain_id, participant_data, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_participant_Success_Governance)
{

  ::DDS::Security::DomainId_t domain_id = 0;
  ::DDS::Security::ParticipantBuiltinTopicDataSecure participant_data;
  ::DDS::Security::PermissionsToken remote_perm_token;
  ::DDS::Security::AuthenticatedPeerCredentialToken remote_apc_token;
  ::DDS::Security::SecurityException ex;

  remote_perm_token.class_id = Expected_Permissions_Token_Class_Id;
  remote_perm_token.properties.length(1);
  remote_perm_token.properties[0].name = "dds.perm.ca.sn";
  remote_perm_token.properties[0].value = remote_subject_name;

  std::string id(get_file_contents(mock_1_cert_file));
  std::string pf(get_file_contents(perm_mock_1_join_p7s_file));

  remote_apc_token.class_id = Expected_Permissions_Cred_Token_Class_Id;
  remote_apc_token.binary_properties.length(2);
  remote_apc_token.binary_properties[0].name = "c.id";
  remote_apc_token.binary_properties[0].value.length(static_cast<CORBA::ULong>(id.size()));
  memcpy(remote_apc_token.binary_properties[0].value.get_buffer(), id.c_str(), id.size());
  remote_apc_token.binary_properties[0].propagate = true;

  remote_apc_token.binary_properties[1].name = "c.perm";
  remote_apc_token.binary_properties[1].value.length(static_cast<CORBA::ULong>(pf.size()));
  memcpy(remote_apc_token.binary_properties[1].value.get_buffer(),pf.c_str(), pf.size());
  remote_apc_token.binary_properties[1].propagate = true;

  get_inst().validate_local_permissions(auth_plugin_.get(), 1, 1, domain_participant_qos_, ex);

  ::DDS::Security::PermissionsHandle remote_out_handle = get_inst().validate_remote_permissions(
          auth_plugin_.get(), 1, 2, remote_perm_token, remote_apc_token, ex);

  EXPECT_TRUE(get_inst().check_remote_participant(
    remote_out_handle, domain_id, participant_data, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_participant_Success_Permissions)
{
  ::DDS::Security::DomainId_t domain_id = 0;
  ::DDS::Security::ParticipantBuiltinTopicDataSecure participant_data;
  ::DDS::Security::PermissionsToken remote_perm_token;
  ::DDS::Security::AuthenticatedPeerCredentialToken remote_apc_token;
  ::DDS::Security::SecurityException ex;

  add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::gov_6_p7s_);

  participant_data.base.permissions_token.class_id = Expected_Permissions_Token_Class_Id;

  remote_perm_token.class_id = Expected_Permissions_Token_Class_Id;
  remote_perm_token.properties.length(1);
  remote_perm_token.properties[0].name = "dds.perm.ca.sn";
  remote_perm_token.properties[0].value = remote_subject_name;

  std::string id(get_file_contents(mock_1_cert_file));
  std::string pf(get_file_contents(perm_mock_1_join_p7s_file));

  remote_apc_token.class_id = Expected_Permissions_Cred_Token_Class_Id;
  remote_apc_token.binary_properties.length(2);
  remote_apc_token.binary_properties[0].name = "c.id";
  remote_apc_token.binary_properties[0].value.length(static_cast<CORBA::ULong>(id.size()));
  memcpy(remote_apc_token.binary_properties[0].value.get_buffer(), id.c_str(), id.size());
  remote_apc_token.binary_properties[0].propagate = true;

  remote_apc_token.binary_properties[1].name = "c.perm";
  remote_apc_token.binary_properties[1].value.length(static_cast<CORBA::ULong>(pf.size()));
  memcpy(remote_apc_token.binary_properties[1].value.get_buffer(), pf.c_str(), pf.size());
  remote_apc_token.binary_properties[1].propagate = true;

  get_inst().validate_local_permissions(auth_plugin_.get(), 1, domain_id, domain_participant_qos_, ex);

  ::DDS::Security::PermissionsHandle remote_out_handle = get_inst().validate_remote_permissions(
    auth_plugin_.get(), 1, 2, remote_perm_token, remote_apc_token, ex);

  EXPECT_TRUE(get_inst().check_remote_participant(
    remote_out_handle, domain_id, participant_data, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_datawriter_InvalidInput)
{
  ::DDS::Security::DomainId_t domain_id = 1;
  ::DDS::Security::PublicationBuiltinTopicDataSecure publication_data;
  ::DDS::Security::SecurityException ex;

  // Nil input handle
  EXPECT_FALSE(get_inst().check_remote_datawriter(
    DDS::HANDLE_NIL, domain_id, publication_data, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_datawriter_Success)
{
  ::DDS::Security::AuthenticatedPeerCredentialToken remote_apc_token;
  ::DDS::Security::DomainId_t domain_id = 0;
  ::DDS::Security::PermissionsToken remote_perm_token;
  ::DDS::Security::PublicationBuiltinTopicDataSecure publication_data;
  ::DDS::Security::SecurityException ex;

  remote_perm_token.class_id = Expected_Permissions_Token_Class_Id;
  remote_perm_token.properties.length(1);
  remote_perm_token.properties[0].name = "dds.perm.ca.sn";
  remote_perm_token.properties[0].value = remote_subject_name;

  std::string id(get_file_contents(mock_1_cert_file));
  std::string pf(get_file_contents(perm_mock_1_join_p7s_file));

  remote_apc_token.class_id = Expected_Permissions_Cred_Token_Class_Id;
  remote_apc_token.binary_properties.length(2);
  remote_apc_token.binary_properties[0].name = "c.id";
  remote_apc_token.binary_properties[0].value.length(static_cast<CORBA::ULong>(id.size()));
  memcpy(remote_apc_token.binary_properties[0].value.get_buffer(), id.c_str(), id.size());
  remote_apc_token.binary_properties[0].propagate = true;
  remote_apc_token.binary_properties[1].name = "c.perm";
  remote_apc_token.binary_properties[1].value.length(static_cast<CORBA::ULong>(pf.size()));
  memcpy(remote_apc_token.binary_properties[1].value.get_buffer(), pf.c_str(), pf.size());
  remote_apc_token.binary_properties[1].propagate = true;
  get_inst().validate_local_permissions(auth_plugin_.get(), 1, 1, domain_participant_qos_, ex);

  ::DDS::Security::PermissionsHandle remote_out_handle = get_inst().validate_remote_permissions(
    auth_plugin_.get(), 1, 2, remote_perm_token, remote_apc_token, ex);

  // In permissions file topic is '*'
  publication_data.base.base.topic_name = "Square";

  EXPECT_TRUE(get_inst().check_remote_datawriter(
    remote_out_handle, domain_id, publication_data, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_datawriter_action_validity_Fail)
{
  ::DDS::Security::AuthenticatedPeerCredentialToken remote_apc_token;
  ::DDS::Security::DomainId_t domain_id = 0;
  ::DDS::Security::PermissionsToken remote_perm_token;
  ::DDS::Security::PublicationBuiltinTopicDataSecure publication_data;
  ::DDS::Security::SecurityException ex;

  remote_perm_token.class_id = Expected_Permissions_Token_Class_Id;
  remote_perm_token.properties.length(1);
  remote_perm_token.properties[0].name = "dds.perm.ca.sn";
  remote_perm_token.properties[0].value = remote_subject_name;

  std::string id(get_file_contents(mock_1_cert_file));
  std::string pf(get_file_contents("../security/permissions/permissions_test_participant_01_ActionValidity_signed.p7s"));

  remote_apc_token.class_id = Expected_Permissions_Cred_Token_Class_Id;
  remote_apc_token.binary_properties.length(2);
  remote_apc_token.binary_properties[0].name = "c.id";
  remote_apc_token.binary_properties[0].value.length(static_cast<CORBA::ULong>(id.size()));
  memcpy(remote_apc_token.binary_properties[0].value.get_buffer(), id.c_str(), id.size());
  remote_apc_token.binary_properties[0].propagate = true;
  remote_apc_token.binary_properties[1].name = "c.perm";
  remote_apc_token.binary_properties[1].value.length(static_cast<CORBA::ULong>(pf.size()));
  memcpy(remote_apc_token.binary_properties[1].value.get_buffer(), pf.c_str(), pf.size());
  remote_apc_token.binary_properties[1].propagate = true;
  add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::gov_6_p7s_);
  get_inst().validate_local_permissions(auth_plugin_.get(), 1, 1, domain_participant_qos_, ex);

  ::DDS::Security::PermissionsHandle remote_out_handle = get_inst().validate_remote_permissions(
    auth_plugin_.get(), 1, 2, remote_perm_token, remote_apc_token, ex);

  // In permissions file topic is '*'
  publication_data.base.base.topic_name = "Triangle";

  EXPECT_FALSE(get_inst().check_remote_datawriter(
    remote_out_handle, domain_id, publication_data, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_datareader_InvalidInput)
{
  ::DDS::Security::DomainId_t domain_id = 1;
  ::DDS::Security::SubscriptionBuiltinTopicDataSecure subscription_data;
  ::DDS::Security::SecurityException ex;
   bool relay_only = true;

  // Nil input handle
  EXPECT_FALSE(get_inst().check_remote_datareader(
    DDS::HANDLE_NIL, domain_id, subscription_data, relay_only, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_datareader_Success)
{
  ::DDS::Security::AuthenticatedPeerCredentialToken remote_apc_token;
  ::DDS::Security::DomainId_t domain_id = 0;
  ::DDS::Security::PermissionsToken remote_perm_token;
  ::DDS::Security::SubscriptionBuiltinTopicDataSecure subscription_data;
  ::DDS::Security::SecurityException ex;
  bool relay_only = true;

  remote_perm_token.class_id = Expected_Permissions_Token_Class_Id;
  remote_perm_token.properties.length(1);
  remote_perm_token.properties[0].name = "dds.perm.ca.sn";
  remote_perm_token.properties[0].value = remote_subject_name;

  std::string id(get_file_contents(mock_1_cert_file));
  std::string pf(get_file_contents(perm_mock_1_join_p7s_file));

  remote_apc_token.class_id = Expected_Permissions_Cred_Token_Class_Id;
  remote_apc_token.binary_properties.length(2);
  remote_apc_token.binary_properties[0].name = "c.id";
  remote_apc_token.binary_properties[0].value.length(static_cast<CORBA::ULong>(id.size()));
  memcpy(remote_apc_token.binary_properties[0].value.get_buffer(), id.c_str(), id.size());
  remote_apc_token.binary_properties[0].propagate = true;
  remote_apc_token.binary_properties[1].name = "c.perm";
  remote_apc_token.binary_properties[1].value.length(static_cast<CORBA::ULong>(pf.size()));
  memcpy(remote_apc_token.binary_properties[1].value.get_buffer(), pf.c_str(), pf.size());
  remote_apc_token.binary_properties[1].propagate = true;
  get_inst().validate_local_permissions(auth_plugin_.get(), 1, 1, domain_participant_qos_, ex);

  ::DDS::Security::PermissionsHandle remote_out_handle = get_inst().validate_remote_permissions(
    auth_plugin_.get(), 1, 2, remote_perm_token, remote_apc_token, ex);

  // In permissions file topic is '*'
  subscription_data.base.base.topic_name = "Square";

  EXPECT_TRUE(get_inst().check_remote_datareader(
    remote_out_handle, domain_id, subscription_data, relay_only, ex));
  EXPECT_FALSE(relay_only);
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_datareader_action_validity_Fail)
{
  ::DDS::Security::AuthenticatedPeerCredentialToken remote_apc_token;
  ::DDS::Security::DomainId_t domain_id = 0;
  ::DDS::Security::PermissionsToken remote_perm_token;
  ::DDS::Security::SubscriptionBuiltinTopicDataSecure subscription_data;
  ::DDS::Security::SecurityException ex;
  bool relay_only = true;

  remote_perm_token.class_id = Expected_Permissions_Token_Class_Id;
  remote_perm_token.properties.length(1);
  remote_perm_token.properties[0].name = "dds.perm.ca.sn";
  remote_perm_token.properties[0].value = remote_subject_name;

  std::string id(get_file_contents(mock_1_cert_file));
  std::string pf(get_file_contents("../security/permissions/permissions_test_participant_01_ActionValidity_signed.p7s"));

  remote_apc_token.class_id = Expected_Permissions_Cred_Token_Class_Id;
  remote_apc_token.binary_properties.length(2);
  remote_apc_token.binary_properties[0].name = "c.id";
  remote_apc_token.binary_properties[0].value.length(static_cast<CORBA::ULong>(id.size()));
  memcpy(remote_apc_token.binary_properties[0].value.get_buffer(), id.c_str(), id.size());
  remote_apc_token.binary_properties[0].propagate = true;
  remote_apc_token.binary_properties[1].name = "c.perm";
  remote_apc_token.binary_properties[1].value.length(static_cast<CORBA::ULong>(pf.size()));
  memcpy(remote_apc_token.binary_properties[1].value.get_buffer(), pf.c_str(), pf.size());
  remote_apc_token.binary_properties[1].propagate = true;
  add_or_replace_property(dds_DCPS_security_AccessControlBuiltInImpl::gov_6_p7s_);
  get_inst().validate_local_permissions(auth_plugin_.get(), 1, 1, domain_participant_qos_, ex);

  ::DDS::Security::PermissionsHandle remote_out_handle = get_inst().validate_remote_permissions(
    auth_plugin_.get(), 1, 2, remote_perm_token, remote_apc_token, ex);

  // In permissions file topic is '*'
  subscription_data.base.base.topic_name = "Square";

  EXPECT_FALSE(get_inst().check_remote_datareader(
    remote_out_handle, domain_id, subscription_data, relay_only, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_topic_InvalidInput)
{
  ::DDS::Security::DomainId_t domain_id = 1;
  ::DDS::TopicBuiltinTopicData topic_data;
  ::DDS::Security::SecurityException ex;

  // Nil input handle
  EXPECT_FALSE(get_inst().check_remote_topic(
    DDS::HANDLE_NIL, domain_id, topic_data, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_topic_Success)
{
  ::DDS::Security::DomainId_t domain_id = 0;
  ::DDS::TopicBuiltinTopicData topic_data;
  ::DDS::Security::PermissionsToken remote_perm_token;
  ::DDS::Security::AuthenticatedPeerCredentialToken remote_apc_token;
  ::DDS::Security::SecurityException ex;

  ::DDS::Security::PermissionsHandle local_permissions_handle =
          get_inst().validate_local_permissions(auth_plugin_.get(), 1, domain_id, domain_participant_qos_, ex);

  EXPECT_TRUE(local_permissions_handle != DDS::HANDLE_NIL);

  remote_perm_token.class_id = Expected_Permissions_Token_Class_Id;
  remote_perm_token.properties.length(1);
  remote_perm_token.properties[0].name = "dds.perm.ca.sn";
  remote_perm_token.properties[0].value = remote_subject_name;

  std::string id(get_file_contents(mock_1_cert_file));
  std::string pf(get_file_contents(perm_mock_1_join_p7s_file));

  remote_apc_token.class_id = Expected_Permissions_Cred_Token_Class_Id;
  remote_apc_token.binary_properties.length(2);
  remote_apc_token.binary_properties[0].name = "c.id";
  remote_apc_token.binary_properties[0].value.length(static_cast<CORBA::ULong>(id.size()));
  memcpy(remote_apc_token.binary_properties[0].value.get_buffer(), id.c_str(), id.size());
  remote_apc_token.binary_properties[0].propagate = true;

  remote_apc_token.binary_properties[1].name = "c.perm";
  remote_apc_token.binary_properties[1].value.length(static_cast<CORBA::ULong>(pf.size()));
  memcpy(remote_apc_token.binary_properties[1].value.get_buffer(), pf.c_str(), pf.size());
  remote_apc_token.binary_properties[1].propagate = true;

  ::DDS::Security::PermissionsHandle remote_permissions_handle =
    get_inst().validate_remote_permissions(auth_plugin_.get(), 1, 2, remote_perm_token, remote_apc_token, ex);

  topic_data.name = "Square";

  EXPECT_TRUE(get_inst().check_remote_topic(
    remote_permissions_handle, domain_id, topic_data, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_local_datawriter_match_InvalidInput)
{
  ::DDS::Security::PermissionsHandle writer_handle = 1;
  ::DDS::Security::PermissionsHandle reader_handle = 2;
  ::DDS::Security::PublicationBuiltinTopicDataSecure publication_data;
  ::DDS::Security::SubscriptionBuiltinTopicDataSecure subscription_data;
  ::DDS::Security::SecurityException ex;

  // Nil writer handle
  EXPECT_FALSE(get_inst().check_local_datawriter_match(
    DDS::HANDLE_NIL, reader_handle, publication_data, subscription_data, ex));

  // Nil reader handle
  EXPECT_FALSE(get_inst().check_local_datawriter_match(
    writer_handle, DDS::HANDLE_NIL, publication_data, subscription_data, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_local_datawriter_match_Success)
{
  ::DDS::Security::PermissionsHandle writer_handle = 1;
  ::DDS::Security::PermissionsHandle reader_handle = 2;
  ::DDS::Security::PublicationBuiltinTopicDataSecure publication_data;
  ::DDS::Security::SubscriptionBuiltinTopicDataSecure subscription_data;
  ::DDS::Security::SecurityException ex;

  EXPECT_TRUE(get_inst().check_local_datawriter_match(
    writer_handle, reader_handle, publication_data, subscription_data, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_local_datareader_match_InvalidInput)
{
  ::DDS::Security::PermissionsHandle writer_handle = 1;
  ::DDS::Security::PermissionsHandle reader_handle = 2;
  ::DDS::Security::PublicationBuiltinTopicDataSecure publication_data;
  ::DDS::Security::SubscriptionBuiltinTopicDataSecure subscription_data;
  ::DDS::Security::SecurityException ex;

  // Nil writer handle
  EXPECT_FALSE(get_inst().check_local_datareader_match(
    DDS::HANDLE_NIL, writer_handle, subscription_data, publication_data, ex));

  // Nil reader handle
  EXPECT_FALSE(get_inst().check_local_datareader_match(
    reader_handle, DDS::HANDLE_NIL, subscription_data, publication_data, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_local_datareader_match_Success)
{
  ::DDS::Security::PermissionsHandle writer_handle = 1;
  ::DDS::Security::PermissionsHandle reader_handle = 2;
  ::DDS::Security::PublicationBuiltinTopicDataSecure publication_data;
  ::DDS::Security::SubscriptionBuiltinTopicDataSecure subscription_data;
  ::DDS::Security::SecurityException ex;

  EXPECT_TRUE(get_inst().check_local_datareader_match(
    reader_handle, writer_handle, subscription_data, publication_data, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_datawriter_register_instance_InvalidInput)
{
  ::DDS::Security::PermissionsHandle perm_handle = 1;
  ::DDS::InstanceHandle_t pub_handle = 2;
  MockDataReader::SmartPtr reader(new MockDataReader());
  FakeDynamicData::SmartPtr key(new FakeDynamicData());
  ::DDS::Security::SecurityException ex;

  // Nil handles
  EXPECT_FALSE(get_inst().check_remote_datawriter_register_instance(
    DDS::HANDLE_NIL, reader.get(), pub_handle, key.get(), ex));
  EXPECT_FALSE(get_inst().check_remote_datawriter_register_instance(
    perm_handle, reader.get(), DDS::HANDLE_NIL, key.get(), ex));

  // Null pointers
  EXPECT_FALSE(get_inst().check_remote_datawriter_register_instance(
    perm_handle, 0, pub_handle, key.get(), ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_datawriter_register_instance_Success)
{
  ::DDS::Security::PermissionsHandle perm_handle = 1;
  ::DDS::InstanceHandle_t pub_handle = 2;
  MockDataReader::SmartPtr reader(new MockDataReader());
  FakeDynamicData::SmartPtr key(new FakeDynamicData());
  ::DDS::Security::SecurityException ex;

  EXPECT_TRUE(get_inst().check_remote_datawriter_register_instance(
    perm_handle, reader.get(), pub_handle, key.get(), ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, check_remote_datawriter_dispose_instance_InvalidInput)
{
  ::DDS::Security::PermissionsHandle perm_handle = 1;
  ::DDS::InstanceHandle_t pub_handle = 2;
  MockDataReader::SmartPtr reader(new MockDataReader());
  FakeDynamicData::SmartPtr key(new FakeDynamicData());
  ::DDS::Security::SecurityException ex;

  // Nil handles
  EXPECT_FALSE(get_inst().check_remote_datawriter_dispose_instance(
    DDS::HANDLE_NIL, reader.get(), pub_handle, key.get(), ex));
  EXPECT_FALSE(get_inst().check_remote_datawriter_dispose_instance(
    perm_handle, reader.get(), DDS::HANDLE_NIL, key.get(), ex));

  // Null pointers
  EXPECT_FALSE(get_inst().check_remote_datawriter_dispose_instance(
    perm_handle, 0, pub_handle, key.get(), ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, get_permissions_token_InvalidInput)
{
  ::DDS::Security::PermissionsToken token;
  ::DDS::Security::SecurityException ex;

  // Nil handle
  EXPECT_FALSE(get_inst().get_permissions_token(token, DDS::HANDLE_NIL, ex));

}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, get_permissions_token_Success)
{

  ::DDS::DomainParticipantQos qos;
  ::DDS::Security::SecurityException ex;

  ::DDS::Security::PermissionsHandle perm_handle = get_inst().validate_local_permissions(auth_plugin_.get(), 1, 1, domain_participant_qos_, ex);

  ::DDS::Security::PermissionsToken token;

  EXPECT_TRUE(get_inst().get_permissions_token(token, perm_handle, ex));
  EXPECT_STREQ(Expected_Permissions_Token_Class_Id, token.class_id);
  ASSERT_EQ(0U, token.properties.length());

}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, get_permissions_credential_token_InvalidInput)
{
  ::DDS::Security::PermissionsCredentialToken token;
  ::DDS::Security::SecurityException ex;

  // Nil handle
  EXPECT_FALSE(get_inst().get_permissions_credential_token(token, DDS::HANDLE_NIL, ex));

}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, get_permissions_credential_token_Success)
{
  ::DDS::Security::PermissionsHandle perm_handle = 1;
  ::DDS::Security::PermissionsCredentialToken token;
  ::DDS::Security::SecurityException ex;
  ::DDS::DomainParticipantQos qos;

  EXPECT_TRUE(get_inst().validate_local_permissions(auth_plugin_.get(), 1, 1, domain_participant_qos_, ex));

  std::string f(domain_participant_qos_.property.value[2].value);
  std::string comp_file_ = get_file_contents(extract_file_name(f).c_str());

  EXPECT_TRUE(get_inst().get_permissions_credential_token(token, perm_handle, ex));
  EXPECT_STREQ(Expected_Permissions_Cred_Token_Class_Id, token.class_id);
  ASSERT_EQ(1U, token.properties.length());
  EXPECT_STREQ("dds.perm.cert", token.properties[0].name);
  EXPECT_STREQ(comp_file_.c_str(), token.properties[0].value);
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, set_listener)
{
  ::DDS::Security::SecurityException ex;

  // Try with null pointer and a good pointer
  MockAccessControlListener::SmartPtr listener(new MockAccessControlListener());
  EXPECT_FALSE(get_inst().set_listener(0, ex));
  EXPECT_TRUE(get_inst().set_listener(listener.get(), ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, return_permissions_token)
{
  ::DDS::Security::PermissionsToken token;
  ::DDS::Security::SecurityException ex;
  EXPECT_TRUE(get_inst().return_permissions_token(token, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, return_permissions_credential_token)
{
  ::DDS::Security::PermissionsCredentialToken token;
  ::DDS::Security::SecurityException ex;
  EXPECT_TRUE(get_inst().return_permissions_credential_token(token, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, get_participant_sec_attributes_InvalidInput)
{
  ::DDS::Security::ParticipantSecurityAttributes attributes;
  ::DDS::Security::SecurityException ex;
  EXPECT_FALSE(get_inst().get_participant_sec_attributes(DDS::HANDLE_NIL, attributes, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, get_participant_sec_attributes_Success)
{
  ::DDS::Security::ParticipantSecurityAttributes attributes;
  ::DDS::Security::SecurityException ex;


  get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);

  EXPECT_TRUE(get_inst().get_participant_sec_attributes(1, attributes, ex));
  EXPECT_TRUE(attributes.allow_unauthenticated_participants);
  EXPECT_FALSE(attributes.is_access_protected);
  EXPECT_FALSE(attributes.is_discovery_protected);
  EXPECT_FALSE(attributes.is_liveliness_protected);
  EXPECT_FALSE(attributes.is_rtps_protected);
  EXPECT_EQ(0x80000000, attributes.plugin_participant_attributes);
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, get_topic_sec_attributes_InvalidInput)
{
  ::DDS::Security::TopicSecurityAttributes attributes;

  ::DDS::Security::SecurityException ex;

  // Nil handle
  EXPECT_FALSE(get_inst().get_topic_sec_attributes(DDS::HANDLE_NIL, "TopicName", attributes, ex));
  // Null topic name
  EXPECT_FALSE(get_inst().get_topic_sec_attributes(1, 0, attributes, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, get_topic_sec_attributes_Success)
{
  ::DDS::Security::TopicSecurityAttributes attributes;
  ::DDS::Security::SecurityException ex;

  get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);

  EXPECT_TRUE(get_inst().get_topic_sec_attributes(1, "Square", attributes, ex));
  EXPECT_FALSE(attributes.is_read_protected);
  EXPECT_FALSE(attributes.is_write_protected);
  EXPECT_FALSE(attributes.is_discovery_protected);
  EXPECT_FALSE(attributes.is_liveliness_protected);
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, get_datawriter_sec_attributes_InvalidInput)
{
  ::DDS::PartitionQosPolicy partition;
  ::DDS::Security::DataTagQosPolicy data_tag;
  ::DDS::Security::EndpointSecurityAttributes attributes;
  ::DDS::Security::SecurityException ex;

  // Nil handle
  EXPECT_FALSE(get_inst().get_datawriter_sec_attributes(
    DDS::HANDLE_NIL, "TestTopic", partition, data_tag, attributes, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, get_datawriter_sec_attributes_Success)
{
  ::DDS::PartitionQosPolicy partition;
  ::DDS::Security::DataTagQosPolicy data_tag;
  ::DDS::Security::EndpointSecurityAttributes attributes;
  ::DDS::Security::SecurityException ex;

  ::DDS::Security::PermissionsHandle permissions_handle =
          get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);

  attributes.plugin_endpoint_attributes = 0;

  EXPECT_TRUE(get_inst().get_datawriter_sec_attributes(
    permissions_handle, "Square", partition, data_tag, attributes, ex));
  EXPECT_FALSE(attributes.is_submessage_protected);
  EXPECT_FALSE(attributes.is_payload_protected);
  EXPECT_FALSE(attributes.is_key_protected);
  EXPECT_EQ(0U, attributes.plugin_endpoint_attributes);
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, get_datareader_sec_attributes_InvalidInput)
{
  ::DDS::PartitionQosPolicy partition;
  ::DDS::Security::DataTagQosPolicy data_tag;
  ::DDS::Security::EndpointSecurityAttributes attributes;
  ::DDS::Security::SecurityException ex;

  // Nil handle
  EXPECT_FALSE(get_inst().get_datareader_sec_attributes(
    DDS::HANDLE_NIL, "TestTopic", partition, data_tag, attributes, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, get_datareader_sec_attributes_Success)
{
  ::DDS::PartitionQosPolicy partition;
  ::DDS::Security::DataTagQosPolicy data_tag;
  ::DDS::Security::EndpointSecurityAttributes attributes;
  ::DDS::Security::SecurityException ex;

  ::DDS::Security::PermissionsHandle permissions_handle =
          get_inst().validate_local_permissions(auth_plugin_.get(), 1, 0, domain_participant_qos_, ex);

  attributes.plugin_endpoint_attributes = 0;

  EXPECT_TRUE(get_inst().get_datawriter_sec_attributes(
          permissions_handle, "Square", partition, data_tag, attributes, ex));
  EXPECT_FALSE(attributes.is_submessage_protected);
  EXPECT_FALSE(attributes.is_payload_protected);
  EXPECT_FALSE(attributes.is_key_protected);
  EXPECT_EQ(0U, attributes.plugin_endpoint_attributes);
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, return_participant_sec_attributes)
{
  ::DDS::Security::ParticipantSecurityAttributes attributes;
  ::DDS::Security::SecurityException ex;
  EXPECT_TRUE(get_inst().return_participant_sec_attributes(attributes, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, return_datawriter_sec_attributes)
{
  ::DDS::Security::EndpointSecurityAttributes attributes;
  ::DDS::Security::SecurityException ex;
  EXPECT_TRUE(get_inst().return_datawriter_sec_attributes(attributes, ex));
}

TEST_F(dds_DCPS_security_AccessControlBuiltInImpl, return_datareader_sec_attributes)
{
  ::DDS::Security::EndpointSecurityAttributes attributes;
  ::DDS::Security::SecurityException ex;
  EXPECT_TRUE(get_inst().return_datareader_sec_attributes(attributes, ex));
}

#endif
